home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 49 / Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso / -screenplay- / otherstuff / inform_lib610 / infix.h < prev    next >
Text File  |  1999-11-29  |  40KB  |  1,026 lines

  1. ! ----------------------------------------------------------------------------
  2. !  INFIX:  Support for the optional library extension "Infix".
  3. !
  4. !  Supplied for use with Inform 6                         Serial number 991106
  5. !                                                                 Release 6/10
  6. !  (c) Graham Nelson 1999
  7. !      but freely usable (see manuals)
  8. ! ----------------------------------------------------------------------------
  9. System_file;
  10. Ifdef DEBUG;
  11.  
  12. Constant INFIXTT_NUMBER 0;
  13. Constant INFIXTT_ARRAY 1;
  14. Constant INFIXTT_ROUTINE 2;
  15. Constant INFIXTT_CONSTANT 3;
  16. Constant INFIXTT_DWORD 4;
  17. Constant INFIXTT_ACTION 5;
  18. Constant INFIXTT_ATTRIBUTE 6;
  19. Constant INFIXTT_PROPERTY 7;
  20. Constant INFIXTT_GLOBAL 8;
  21. Constant INFIXTT_NAMEDOBJECT 9;
  22. Constant INFIXTT_SYSFUN 10;
  23. Constant INFIXTT_STATICSTRING 11;
  24. Constant INFIXTT_LOGICAL 12;
  25.  
  26. Global infix_term_type;
  27. Global infix_data1;
  28. Global infix_data2;
  29. Global infix_lvalue;
  30. Global infix_parsed_lvalue;
  31. Array infix_tolowercase -> 256;
  32. Array infix_text -> 128;
  33.  
  34.  
  35. [ InfixPrintAttribute x; print (string) #attribute_names_array-->x; ];
  36. [ InfixPrintProperty x; print (property) x; ];
  37. [ InfixPrintGlobal x; print (string) #global_names_array-->x; ];
  38. [ InfixPrintAction x;
  39.   print (string) #action_names_array-->(x-#lowest_action_number);
  40. ];
  41. [ InfixPrintRoutine x;
  42.   print (string) #routine_names_array-->(x-#lowest_routine_number);
  43. ];
  44. [ InfixPrintConstant x;
  45.   print (string) #constant_names_array-->(x-#lowest_constant_number);
  46. ];
  47. [ InfixPrintArray x;
  48.   print (string) #array_names_array-->(x-#lowest_array_number);
  49. ];
  50. [ InfixPrintFakeAction x;
  51.   print (string) #fake_action_names_array-->(x-#lowest_fake_action_number);
  52. ];
  53. [ InfixPrintPA x n;
  54.   for (n=#lowest_routine_number:n<=#highest_routine_number:n++)
  55.   {   if (x == Symb__Tab(INFIXTT_ROUTINE, n))
  56.       {   print (InfixPrintRoutine) n; return;
  57.       }
  58.   }
  59.   print "Routine(", x, ")";
  60. ];
  61.  
  62. [ InfixMatchPrule PrintingRule range1 range2 wa wl t i i2 it2 itlc j k plus;
  63.   itlc = infix_tolowercase;
  64.   if (itlc->255 == 0)
  65.   {   for (j=0:j<256:j++) itlc->j = j;
  66.       itlc->'A' = 'a';      itlc->'B' = 'b';
  67.       itlc->'C' = 'c';      itlc->'D' = 'd';
  68.       itlc->'E' = 'e';      itlc->'F' = 'f';
  69.       itlc->'G' = 'g';      itlc->'H' = 'h';
  70.       itlc->'I' = 'i';      itlc->'J' = 'j';
  71.       itlc->'K' = 'k';      itlc->'L' = 'l';
  72.       itlc->'M' = 'm';      itlc->'N' = 'n';
  73.       itlc->'O' = 'o';      itlc->'P' = 'p';
  74.       itlc->'Q' = 'q';      itlc->'R' = 'r';
  75.       itlc->'S' = 's';      itlc->'T' = 't';
  76.       itlc->'U' = 'u';      itlc->'V' = 'v';
  77.       itlc->'W' = 'w';      itlc->'X' = 'x';
  78.       itlc->'Y' = 'y';      itlc->'Z' = 'z';
  79.   }
  80.   switch(PrintingRule)
  81.   {   InfixPrintAttribute:
  82.           if (wa->0 == '~') { wl--; wa++; plus = 100; } ! A tilde
  83.           t = #attribute_names_array;
  84.       InfixPrintProperty: t = #property_names_array;
  85.       InfixPrintAction: t = #action_names_array;
  86.       InfixPrintFakeAction: t = #fake_action_names_array;
  87.       InfixPrintGlobal: t = #global_names_array;
  88.       InfixPrintRoutine: t = #routine_names_array;
  89.       InfixPrintAction: t = #constant_names_array;
  90.       InfixPrintArray: t = #array_names_array;
  91.   }
  92.  
  93.   i2 = range2-range1; it2 = infix_text+2;
  94.   for (i=0: i<=i2: i++)
  95.   {   infix_text-->0 = 62; @output_stream 3 infix_text;
  96.       if (t) print (string) t-->i; else PrintingRule(i+range1);
  97.       @output_stream -3;
  98.       k = infix_text-->0;
  99.       if (k ~= wl) jump XL;
  100.       if (itlc->(it2->0) ~= wa->0) jump XL;
  101.       for (j=1:j<k:j++)
  102.           if (itlc->(it2->j) ~= wa->j) jump XL;
  103.       parsed_number = i + range1 + plus; rtrue;
  104.      .XL;
  105.   }
  106.   rfalse;
  107. ];
  108.  
  109. [ InfixActionToken;
  110.   if (InfixMatchPrule(InfixPrintAction,
  111.       #lowest_action_number, #highest_action_number,
  112.       WordAddress(wn), WordLength(wn)))
  113.   {   wn++; infix_lvalue = parsed_number; return 0;
  114.   }
  115.   if (InfixMatchPrule(InfixPrintFakeAction,
  116.       #lowest_fake_action_number, #highest_fake_action_number,
  117.       WordAddress(wn), WordLength(wn)))
  118.   {   wn++; infix_lvalue = parsed_number; return 0;
  119.   }
  120.   return -1;
  121. ];
  122.  
  123. [ InfixRvalueTerm n w i initial_wn wa wl sign base digit dcount;
  124.  
  125.   initial_wn = wn;
  126.  
  127.   infix_parsed_lvalue = -1;
  128.   infix_term_type = INFIXTT_NUMBER;
  129.  
  130.   w = NextWordStopped();
  131.   if (w == -1) return -1;
  132.  
  133.   wa = WordAddress(wn-1);
  134.   wl = WordLength(wn-1);
  135.   if (wa->0 == '-' or '$' or '0' or '1' or '2' or '3' or '4'
  136.                or '5' or '6' or '7' or '8' or '9')
  137.   {   ! Parse decimal, hex or binary number
  138.  
  139.       sign = 1; base = 10; dcount = 0;
  140.       if (wa->0 == '-') { sign = -1; wl--; wa++; }
  141.       else
  142.       {   if (wa->0 == '$') { base = 16; wl--; wa++; }
  143.           if (wa->0 == '$') { base = 2; wl--; wa++; }
  144.       }
  145.       if (wl == 0) return -1;
  146.       n = 0;
  147.       while (wl > 0)
  148.       {   if (wa->0 >= 'a') digit = wa->0 - 'a' + 10;
  149.           else digit = wa->0 - '0';
  150.           dcount++;
  151.           switch(base)
  152.           {   2: if (dcount == 17) return -1;
  153.              10: if (dcount == 6) return -1;
  154.                  if (dcount == 5)
  155.                  {   if (n > 3276) return -1;
  156.                      if (n == 3276)
  157.                      {   if (sign == 1 && digit > 7) return -1;
  158.                          if (sign == -1 && digit > 8) return -1;
  159.                      }
  160.                  }
  161.              16: if (dcount == 5) return -1;
  162.           }
  163.           if (digit >= 0 && digit < base) n = base*n + digit;
  164.           else return -1;
  165.           wl--; wa++;
  166.       }
  167.       parsed_number = n*sign; return 1;
  168.   }
  169.  
  170. ! Parse character constant 'a'
  171.  
  172.   if (wl == 3 && wa->0==''' && wa->2==''')
  173.   {   parsed_number = wa->1; return 1;
  174.   }
  175.  
  176. ! ##Action, 'dword'
  177.  
  178.   switch(w)
  179.   {   '##': infix_term_type = INFIXTT_ACTION;
  180.             w = NextWordStopped(); if (w == -1) return -1;
  181.             wn--;
  182.             if (InfixActionToken() == 0) return 1;
  183.             return -1;
  184.       '^^': infix_term_type = INFIXTT_DWORD;
  185.             w = NextWordStopped(); if (w == -1) return -1;
  186.             parsed_number = w; return 1;
  187.   }
  188.  
  189. ! Test for attribute, property, class name, variable name, array name, routine
  190. ! name, constant name
  191.  
  192.   wn--;
  193.   if ((wa->0 >= 'a' && wa->0 <= 'z')
  194.       || (wa->0 >= 'A' && wa->0 <= 'Z')
  195.       || wa->0 == '_')
  196.   {
  197.                
  198.   infix_term_type = INFIXTT_ATTRIBUTE;
  199.   if (InfixMatchPrule(InfixPrintAttribute,
  200.       #lowest_attribute_number, #highest_attribute_number, wa, wl))
  201.   {   wn++; return 1; }
  202.  
  203.   infix_term_type = INFIXTT_PROPERTY;
  204.   if (InfixMatchPrule(InfixPrintProperty,
  205.       #lowest_property_number, #highest_property_number, wa, wl))
  206.   {   wn++; return 1; }
  207.  
  208.   infix_term_type = INFIXTT_GLOBAL;
  209.   if (InfixMatchPrule(InfixPrintGlobal,
  210.       #lowest_global_number, #highest_global_number, wa, wl))
  211.   {   infix_parsed_lvalue = parsed_number-16;
  212.       parsed_number = #globals_array-->infix_parsed_lvalue;
  213.       wn++; return 1;
  214.   }
  215.  
  216.   infix_term_type = INFIXTT_ARRAY;
  217.   if (InfixMatchPrule(InfixPrintArray,
  218.       #lowest_array_number, #highest_array_number, wa, wl))
  219.   {   infix_parsed_lvalue = parsed_number;
  220.       parsed_number = Symb__Tab(INFIXTT_ARRAY,parsed_number);
  221.       infix_data1 = temp__global3;
  222.       infix_data2 = temp__global2;
  223.       wn++; return 1;
  224.   }
  225.  
  226.   infix_term_type = INFIXTT_ROUTINE;
  227.   if (InfixMatchPrule(InfixPrintRoutine,
  228.       #lowest_routine_number, #highest_routine_number, wa, wl))
  229.   {   infix_parsed_lvalue = parsed_number;
  230.       parsed_number = Symb__Tab(INFIXTT_ROUTINE,parsed_number);
  231.       infix_data1 = temp__global3;
  232.       infix_data2 = temp__global2;
  233.       wn++; return 1;
  234.   }
  235.  
  236.   infix_term_type = INFIXTT_CONSTANT;
  237.   if (InfixMatchPrule(InfixPrintConstant,
  238.       #lowest_constant_number, #highest_constant_number, wa, wl))
  239.   {   infix_parsed_lvalue = parsed_number;
  240.       parsed_number = Symb__Tab(INFIXTT_CONSTANT,parsed_number);
  241.       infix_data1 = temp__global3;
  242.       infix_data2 = temp__global2;
  243.       wn++; return 1;
  244.   }
  245.  
  246.   switch(w)
  247.   {   'parent', 'child', 'children',
  248.       'random', 'metaclass', 'sibling': parsed_number = w;
  249.           infix_parsed_lvalue = INFIXTT_SYSFUN;
  250.           wn++; return 1;
  251.   }
  252.   }
  253.  
  254.   infix_term_type = INFIXTT_NAMEDOBJECT;
  255.  
  256.   wn = initial_wn; i = ParseToken(SCOPE_TT, InfixBigScope);
  257.  
  258.   if (i == GPR_REPARSE) return i;
  259.   if (i > GPR_MULTIPLE)
  260.   {   print "(", (name) i, " (", i, "))^";
  261.       parsed_number = i; return 1;
  262.   }
  263.   return -1;
  264. ];
  265. [ InfixBigScope x;
  266.   if (scope_stage == 1) return false;  ! No multiples here
  267.   if (scope_stage == 2)
  268.   {   objectloop (x ofclass Object) PlaceInScope(x);
  269.       return true; ! That's the whole scope
  270.   }
  271.   print "; I'm unable to make any sense of that term.^";
  272. ];
  273.  
  274. [ InfixCheckLineSpaced wa wl i force altered;
  275.   for (i = 1 : i <= parse->1 : i++)
  276.   {   wa = WordAddress(i);
  277.       wl = WordLength(i);
  278.       if (wl > 3 && wa->0==''' && wa->(wl-1)==''')
  279.       {   wa->(wl-1) = ' ';
  280.           if (wa->(wl-2) == '/' && wa->(wl-3) == '/')
  281.           {   wa->(wl-2) = ' ';
  282.               wa->(wl-3) = ' ';
  283.           }
  284.           LTI_Insert(wa-buffer, ''');
  285.           LTI_Insert(wa-buffer + 2, ' ');
  286.           altered = true; break;
  287.       }
  288.   }
  289.   for (i = 2 : i < buffer->1 + 2: i++)
  290.   {   force = false;
  291.       if (buffer->i=='-' && buffer->(i+1)=='-' && buffer->(i+2)=='>')
  292.           force = true;
  293.       if (force)
  294.       {   if (i>2 && buffer->(i-1)~=' ')
  295.           {   LTI_Insert(i++, ' '); altered = true;
  296.           }
  297.           if (buffer->(i+3)~=' ')
  298.           {   LTI_Insert(i+3, ' '); i++; altered = true;
  299.           }
  300.           i = i + 2; continue;
  301.       }
  302.  
  303.       if (buffer->i==':' && buffer->(i+1)==':') force = true;
  304.       if (buffer->i=='-' && buffer->(i+1)=='>') force = true;
  305.       if (buffer->i=='.' && buffer->(i+1)=='&')
  306.       {   buffer->i = ']'; force = true;
  307.       }
  308.       if (buffer->i=='.' && buffer->(i+1)=='#')
  309.       {   buffer->i = ']'; force = true;
  310.       }
  311.       if (buffer->i==']' && buffer->(i+1)=='&') force = true;
  312.       if (buffer->i==']' && buffer->(i+1)=='#') force = true;
  313.       if (buffer->i=='+' && buffer->(i+1)=='+') force = true;
  314.       if (buffer->i=='-' && buffer->(i+1)=='-') force = true;
  315.       if (buffer->i=='&' && buffer->(i+1)=='&') force = true;
  316.       if (buffer->i=='|' && buffer->(i+1)=='|') force = true;
  317.       if (buffer->i=='~' && buffer->(i+1)=='~') force = true;
  318.  
  319.       if (buffer->i=='=' && buffer->(i+1)=='=') force = true;
  320.       if (buffer->i=='~' && buffer->(i+1)=='=') force = true;
  321.       if (buffer->i=='>' && buffer->(i+1)=='=') force = true;
  322.       if (buffer->i=='<' && buffer->(i+1)=='=') force = true;
  323.       if (buffer->i=='#' && buffer->(i+1)=='#') force = true;
  324.  
  325.       if (force)
  326.       {   if (i>2 && buffer->(i-1)~=' ')
  327.           {   LTI_Insert(i++, ' '); altered = true;
  328.           }
  329.           if (buffer->(i+2)~=' ')
  330.           {   LTI_Insert(i+2, ' '); i++; altered = true;
  331.           }
  332.           i = i + 1; continue;
  333.       }
  334.  
  335.       if (buffer->i=='+') force = true;
  336.       if (buffer->i=='-') force = true;
  337.       if (buffer->i=='*') force = true;
  338.       if (buffer->i=='/') force = true;
  339.       if (buffer->i=='%') force = true;
  340.       if (buffer->i=='(') force = true;
  341.       if (buffer->i==')') force = true;
  342.       if (buffer->i=='<' && buffer->(i-1)~=';') force = true;
  343.       if (buffer->i=='>') force = true;
  344.       if (buffer->i==',') force = true;
  345.       if (buffer->i=='.') force = true;
  346.       if (buffer->i=='&') force = true;
  347.       if (buffer->i=='|') force = true;
  348.       if (buffer->i=='~') force = true;
  349.       if (buffer->i=='=') force = true;
  350.       if (force)
  351.       {   if (i>2 && buffer->(i-1)~=' ')
  352.           {   LTI_Insert(i++, ' '); altered = true;
  353.           }
  354.           if (buffer->(i+1)~=' ')
  355.           {   LTI_Insert(i+1, ' '); i++; altered = true;
  356.           }
  357.       }
  358.   }
  359.   for (i = 2 : i < buffer->1 + 2: i++)
  360.       if (buffer->i == '~') { buffer->i = '['; altered = true; }
  361.   return altered;
  362. ];
  363.  
  364. Array InfixRV_rvals --> 32;
  365. Array InfixRV_lvals --> 32;
  366. Array InfixRV_op --> 32;
  367. Array InfixRV_lop --> 32;
  368. Array InfixRV_rop --> 32;
  369. Array InfixRV_types --> 32;
  370. Array InfixRV_commas --> 32;
  371.  
  372. [ InfixRvalue acc w i n flag base expecting_term max maxi lop rop lvalside
  373.               a b sysfun_f;
  374.  
  375.   if (InfixCheckLineSpaced()) return GPR_REPARSE;
  376.  
  377. !  w = wn; for (i=0: i<10: i++) { wn = w; InfixRvalueTerm(); print i, "^"; }
  378. !  wn = w;
  379.  
  380.   expecting_term = true; base = 0;
  381.   do
  382.   {   w = NextWordStopped();
  383.       if (expecting_term)
  384.       {   switch(w)
  385.           {   '-//':
  386.                   InfixRV_rvals-->n = 'unary-'; InfixRV_types-->n = base + 8;
  387.               '[//':
  388.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 6;
  389.               '[[':
  390.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 2;
  391.               '++':
  392.                   InfixRV_rvals-->n = 'pre++'; InfixRV_types-->n = base + 9;
  393.               '--':
  394.                   InfixRV_rvals-->n = 'pre--'; InfixRV_types-->n = base + 9;
  395.               '(//':
  396.                   InfixRV_rvals-->n = w; InfixRV_types-->n = -3; base=base+100;
  397.               ')//':
  398.                   InfixRV_rvals-->n = w; InfixRV_types-->n = -3; base=base-100;
  399.                   if (base < 0) { wn--; flag = true; }
  400.               -1: flag = true;
  401.               default:
  402.                   wn--;
  403.                   if (InfixRValueTerm() == 1)
  404.                   {   InfixRV_rvals-->n = parsed_number;
  405.                       InfixRV_lvals-->n = infix_parsed_lvalue;
  406.                       InfixRV_types-->n = -1;
  407.                       expecting_term = false;
  408.                   }
  409.                   else flag = true;
  410.           }
  411.       }
  412.       else
  413.       {   expecting_term = true;
  414.           switch(w)
  415.           {   ',//':
  416.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base;
  417.               '=//':
  418.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 1;
  419.               '&&', '||':
  420.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 2;
  421.               '==', '[=', '>//', '>=', '<//', '<=', 'has', 'hasnt',
  422.               'in', 'notin', 'ofclass', 'provides':
  423.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 3;
  424.               'or':
  425.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 4;
  426.               '+//', '-//':
  427.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 5;
  428.               '*//', '@{2f}//', '%//', '&//', '|//':
  429.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 6;
  430.               '->', '-->':
  431.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 7;
  432.               ']&', ']#':
  433.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 10;
  434.               './/':
  435.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 12;
  436.               '::':
  437.                   InfixRV_rvals-->n = w; InfixRV_types-->n = base + 13;
  438.               '(//':
  439.                   InfixRV_rvals-->n = '(rcall';
  440.                   InfixRV_types-->n = base + 11; base = base + 100;
  441.               ')//':
  442.                   InfixRV_rvals-->n = w; InfixRV_types-->n = -3;
  443.                   base = base - 100;
  444.                   if (base < 0) { wn--; flag = true; }
  445.                   expecting_term = false;
  446.               '++':
  447.                   InfixRV_rvals-->n = 'post++'; InfixRV_types-->n = base + 9;
  448.                   expecting_term = false;
  449.               '--':
  450.                   InfixRV_rvals-->n = 'post--'; InfixRV_types-->n = base + 9;
  451.                   expecting_term = false;
  452.               default:
  453.                   flag = true;
  454.           }
  455.       }
  456.       n++;
  457.   } until (flag || n==32);
  458.   if (base > 0) return -1;
  459.   n--; if (n == 0) return -1;
  460.   wn--;
  461.  
  462.   for (i=0: i<n: i++)
  463.   {   acc = 0; if (InfixRV_types-->i ~= -3) acc = InfixRV_rvals-->i;
  464.       InfixRV_op-->i = acc;
  465.   }
  466.  
  467.   for (::)
  468.   {   
  469. !      for (i=0: i<n: i++)
  470. !      {   if (InfixRV_types-->i == -1) print InfixRV_rvals-->i, " ";
  471. !          else if (InfixRV_types-->i == -3) print " # ";
  472. !          else if (InfixRV_types-->i == -2) print " ## ";
  473. !          else print (address) InfixRV_rvals-->i, "_", InfixRV_types-->i, " ";
  474. !      }
  475. !      new_line;
  476.  
  477.       max = -2;
  478.       for (i=0:i<n:i++) if (InfixRV_types-->i > max)
  479.                         { max = InfixRV_types-->i; maxi = i; }
  480.       if (max == -1) { parsed_number = InfixRV_rvals-->maxi; return 1; }
  481.  
  482.       lop = maxi-1; rop = maxi+1;
  483.       while (lop>=0 && InfixRV_types-->lop < -1) lop--;
  484.       while (rop<n && InfixRV_types-->rop < -1) rop++;
  485.       if (lop>=0) InfixRV_lop-->maxi = InfixRV_rvals-->lop;
  486.       if (rop<n) InfixRV_rop-->maxi = InfixRV_rvals-->rop;
  487.       flag = false;
  488.     infix_term_type = INFIXTT_NUMBER;
  489.     switch(InfixRV_rvals-->maxi)
  490.     { ',//':     acc = (InfixRV_rvals-->rop);
  491.       '=//', 'pre++', 'post++', 'pre--', 'post--':
  492.                  lvalside = lop;
  493.                  switch(InfixRV_rvals-->maxi)
  494.                  {   '=//': acc = (InfixRV_rvals-->rop);
  495.                      'pre++': acc = (InfixRV_rvals-->rop) + 1; lvalside = rop;
  496.                      'pre--': acc = (InfixRV_rvals-->rop) - 1; lvalside = rop;
  497.                      'post++': acc = (InfixRV_rvals-->lop) + 1;
  498.                      'post--': acc = (InfixRV_rvals-->lop) - 1;
  499.                  }
  500.                  switch (InfixRV_op-->lvalside)
  501.                  {   './/':
  502.                        (InfixRV_lop-->lvalside).(InfixRV_rop-->lvalside) = acc;
  503.                      '->':
  504.                        (InfixRV_lop-->lvalside)->(InfixRV_rop-->lvalside) = acc;
  505.                      '-->':
  506.                        (InfixRV_lop-->lvalside)-->(InfixRV_rop-->lvalside) = acc;
  507.                      default:
  508.                          w = InfixRV_lvals-->lvalside; if (w == -1) return -1;
  509.                          @storew #globals_array w acc;
  510.                  }
  511.                  switch(InfixRV_rvals-->maxi)
  512.                  {   'post++': acc--;
  513.                      'post--': acc++;
  514.                  }
  515.       '(rcall':  sysfun_f = false;
  516.                  switch (InfixRV_op-->lop)
  517.                  {   './/': a = InfixRV_lop-->lop; b = InfixRV_rop-->lop;
  518.                      default:
  519.                          a = InfixRV_rvals-->lop; b = call;
  520.                          if (InfixRV_lvals-->lop == INFIXTT_SYSFUN)
  521.                              sysfun_f = true;
  522.                  }
  523.                  w = 0;
  524.                  i = maxi + 1; base = 100;
  525.                  if (InfixRV_types-->i == -1 && InfixRV_rvals-->i == ')//')
  526.                  {   if (sysfun_f) return -1;
  527.                      acc = a.b();
  528.                  }
  529.                  else
  530.                  {   while (base > 0)
  531.                      {   if (InfixRV_types-->i == -3 && InfixRV_rvals-->i == ')//')
  532.                              base = base - 100;
  533.                          if (InfixRV_types-->i == -3 && InfixRV_rvals-->i == '(//')
  534.                              base = base + 100;
  535.                          if (InfixRV_op-->i=='(rcall') base = base + 100;
  536.                          if (base == 100 && InfixRV_op-->i == ',//')
  537.                          {   InfixRV_commas-->(w++) = i;
  538. !                             print "Comma found at ", i, "^";
  539.                          }
  540.                          i++;
  541.                      }
  542. !                     print "Num args = ", w + 1, "^";
  543. !                     for (i = 0 : i < w : i++)
  544. !                         print "arg: ", InfixRV_lop-->(InfixRV_commas-->i), "^";
  545. !                     print "arg: ", InfixRV_rvals-->rop, "^";
  546.                      switch(w+1)
  547.                      {   1: if (sysfun_f)
  548.                             {   b = InfixRV_rvals-->rop;
  549.                                 infix_term_type = INFIXTT_NAMEDOBJECT;
  550.                                 switch(a)
  551.                                 {   'metaclass': acc = metaclass(b);
  552.                                     'parent': acc = parent(b);
  553.                                     'child': acc = child(b);
  554.                                     'children': acc = children(b);
  555.                                          infix_term_type = INFIXTT_NUMBER;
  556.                                     'random': acc = random(b);
  557.                                          infix_term_type = INFIXTT_NUMBER;
  558.                                     'sibling': acc = sibling(b);
  559.                                 }
  560.                             }
  561.                             else
  562.                                 acc = a.b(InfixRV_rvals-->rop);
  563.                          2: if (sysfun_f) return -1;
  564.                             acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
  565.                                       InfixRV_rvals-->rop);
  566.                          3: if (sysfun_f) return -1;
  567.                             acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
  568.                                       InfixRV_lop-->(InfixRV_commas-->1),
  569.                                       InfixRV_rvals-->rop);
  570.                          4: if (sysfun_f) return -1;
  571.                             acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
  572.                                       InfixRV_lop-->(InfixRV_commas-->1),
  573.                                       InfixRV_lop-->(InfixRV_commas-->2),
  574.                                       InfixRV_rvals-->rop);
  575.                          5: if (sysfun_f) return -1;
  576.                             acc = a.b(InfixRV_lop-->(InfixRV_commas-->0),
  577.                                       InfixRV_lop-->(InfixRV_commas-->1),
  578.                                       InfixRV_lop-->(InfixRV_commas-->2),
  579.                                       InfixRV_lop-->(InfixRV_commas-->3),
  580.                                       InfixRV_rvals-->rop);
  581.                          default: return -1;
  582.                      }                     
  583.                  }
  584.       '+//':     acc = (InfixRV_rvals-->lop) + (InfixRV_rvals-->rop);
  585.       '-//':     acc = (InfixRV_rvals-->lop) - (InfixRV_rvals-->rop);
  586.       '*//':     acc = (InfixRV_rvals-->lop) * (InfixRV_rvals-->rop);
  587.       '@{2f}//': acc = (InfixRV_rvals-->lop) / (InfixRV_rvals-->rop);
  588.       '%//':     acc = (InfixRV_rvals-->lop) % (InfixRV_rvals-->rop);
  589.       './/':     acc = (InfixRV_rvals-->lop) . (InfixRV_rvals-->rop);
  590.       '->':      acc = (InfixRV_rvals-->lop) -> (InfixRV_rvals-->rop);
  591.       '-->':     acc = (InfixRV_rvals-->lop) --> (InfixRV_rvals-->rop);
  592.       ']&':      acc = (InfixRV_rvals-->lop) .& (InfixRV_rvals-->rop);
  593.       ']#':      acc = (InfixRV_rvals-->lop) .# (InfixRV_rvals-->rop);
  594.       '::':      acc = (InfixRV_rvals-->lop) :: (InfixRV_rvals-->rop);
  595.       '&//':     acc = (InfixRV_rvals-->lop) & (InfixRV_rvals-->rop);
  596.       '|//':     acc = (InfixRV_rvals-->lop) | (InfixRV_rvals-->rop);
  597.       '&&':      acc = (InfixRV_rvals-->lop) && (InfixRV_rvals-->rop);
  598.                  infix_term_type = INFIXTT_LOGICAL;
  599.       '||':      acc = (InfixRV_rvals-->lop) || (InfixRV_rvals-->rop);
  600.                  infix_term_type = INFIXTT_LOGICAL;
  601.       '<//':     acc = (InfixRV_rvals-->lop) < (InfixRV_rvals-->rop);
  602.                  infix_term_type = INFIXTT_LOGICAL;
  603.       '<=':      acc = (InfixRV_rvals-->lop) <= (InfixRV_rvals-->rop);
  604.                  infix_term_type = INFIXTT_LOGICAL;
  605.       '>//':     acc = (InfixRV_rvals-->lop) > (InfixRV_rvals-->rop);
  606.                  infix_term_type = INFIXTT_LOGICAL;
  607.       '>=':      acc = (InfixRV_rvals-->lop) >= (InfixRV_rvals-->rop);
  608.                  infix_term_type = INFIXTT_LOGICAL;
  609.       '==':      acc = (InfixRV_rvals-->lop) == (InfixRV_rvals-->rop);
  610.                  infix_term_type = INFIXTT_LOGICAL;
  611.       '[=':  acc = (InfixRV_rvals-->lop) ~= (InfixRV_rvals-->rop);
  612.                  infix_term_type = INFIXTT_LOGICAL;
  613.       'has':     acc = (InfixRV_rvals-->lop) has (InfixRV_rvals-->rop);
  614.                  infix_term_type = INFIXTT_LOGICAL;
  615.       'hasnt':   acc = (InfixRV_rvals-->lop) hasnt (InfixRV_rvals-->rop);
  616.                  infix_term_type = INFIXTT_LOGICAL;
  617.       'in':      acc = (InfixRV_rvals-->lop) in (InfixRV_rvals-->rop);
  618.                  infix_term_type = INFIXTT_LOGICAL;
  619.       'notin':   acc = (InfixRV_rvals-->lop) notin (InfixRV_rvals-->rop);
  620.                  infix_term_type = INFIXTT_LOGICAL;
  621.       'provides': acc = (InfixRV_rvals-->lop) provides (InfixRV_rvals-->rop);
  622.                  infix_term_type = INFIXTT_LOGICAL;
  623.       'ofclass': acc = (InfixRV_rvals-->lop) ofclass (InfixRV_rvals-->rop);
  624.                  infix_term_type = INFIXTT_LOGICAL;
  625.       '[[':      acc = ~~ (InfixRV_rvals-->rop); flag = true;
  626.       '[//':     acc = ~ (InfixRV_rvals-->rop); flag = true;
  627.       'unary-':  acc = - (InfixRV_rvals-->rop); flag = true;
  628.     }
  629.       InfixRV_rvals-->maxi = acc;
  630.       InfixRV_types-->maxi = -1;
  631.       if (rop < n) InfixRV_types-->rop = -2;
  632.       if (flag==false && lop >= 0) InfixRV_types-->lop = -2;
  633.   }
  634. ];
  635.  
  636. ! ------------------------------------------------------------------------
  637.  
  638. [ InfixWelcomeSub;
  639.   print "; Welcome to the ~Infix~ debugger (1/990428), which makes the
  640.       following verbs available:^^
  641.       ~; <expression>~: evaluates this Inform expression: e.g.
  642.       ~; location~ will print the value of the variable ~location~,
  643.       ~; 3*5+1~ will print 16, ~; children(old cloth bag)~ will tell you
  644.       how many items are in it. (You can name objects either by their
  645.       names inside the source code, such as ~n_obj~, or by typing the
  646.       names by which the game's parser would normally know them, such
  647.       as ~north wall~: the effect is the same.)^
  648.       Any expression is allowed except that you can't use double-quoted
  649.       strings of text: but you can send messages, call routines or
  650.       assign values to variables, properties and array entries.
  651.       ^   ~; score++~ is one way to get on in the world.
  652.       ^   ~; deadflag = true~ is one way to get out of it.
  653.       ^   ~; StopDaemon(nasty little dwarf)~ will keep you from being pestered.^
  654.       Conditions like ~; score>20~ are also allowed and print
  655.       either 1 (if true) or 0 (if false).^^";
  656.   print "~;examine <something>~ or ~;x <something>~ gives full details
  657.       of whatever it is. For instance, ~;x ##Take~ describes the Take
  658.       action; ~;x Class~ the class Class; ~;x 'drop'~ the dictionary
  659.       word ~drop~ and so on for numbers, routines, arrays and of course
  660.       objects.  ~;xo~ examines something as an object, so for instance
  661.       ~;x location~ tells you about the variable ~location~, but ~;xo
  662.       location~ tells you what object it refers to.^^";
  663.   print "~;give~, ~;remove~ and ~;move~ work like the corresponding
  664.       Inform statements.^^";
  665.   print "~;<~ causes an action: for instance, ~;< Eat cheese~.^^";
  666.   print "~;watch~ or ~;w~ can set a watch on various activities:
  667.       type just ~;w~ for details.^^";
  668.   print "~;inventory~ or ~;i~ describes the contents of this story file.^";
  669. ];
  670. [ InfixEvalSub;
  671.   InfixExamineP(true);
  672. ];
  673. [ InfixActionSub;
  674.   print "; <", (InfixPrintAction) infix_lvalue;
  675.   if (noun) print " (", (the) noun, ")";
  676.   if (second) print " (", (the) second, ")";
  677.   print ">^";
  678.   if (second) <<(infix_lvalue) noun second>>;
  679.   if (noun) <<(infix_lvalue) noun>>;
  680.   <<(infix_lvalue)>>;
  681. ];
  682. [ InfixGiveSub f;
  683.   print "; give (", (the) noun, ") ";
  684.   if (second<0) { second = ~second; f=true; }
  685.   if (second < 0 || second>=48) "<No such attribute>";
  686.   if (f) print "@@126";
  687.   print (DebugAttribute) second;
  688.   if (f) @clear_attr noun second;
  689.   else @set_attr noun second;
  690. ];
  691. [ InfixMoveSub;
  692.   print "; move (", (the) noun, ") to (", (the) second, ")";
  693.   move noun to second;
  694. ];
  695. [ InfixRemoveSub;
  696.   print "; remove (", (the) noun, ")";
  697.   remove noun;
  698. ];
  699. [ InfixHex x y;
  700.       y = (x & $7f00) / $100;
  701.       if (x<0) y=y+$80;
  702.       x = x & $ff;
  703.       print (Infixhexdigit) y/$10, (Infixhexdigit) y,
  704.             (Infixhexdigit) x/$10, (Infixhexdigit) x;
  705. ];
  706. [ Infixhexdigit x;
  707.   x = x % $10; if (x<10) print x; else print (char) 'a'+x-10;
  708. ];
  709. [ InfixExamineOSub;
  710.   infix_data1 = metaclass(noun);
  711.   infix_term_type = INFIXTT_CONSTANT;
  712.   InfixExamineP(false);
  713. ];
  714. [ InfixExamineSSub;
  715.   infix_term_type = INFIXTT_STATICSTRING;
  716.   InfixExamineP(false);
  717. ];
  718. [ InfixExamineSub;
  719.   InfixExamineP(false);
  720. ];
  721. [ InfixExamineP brief x a b w flag lines;
  722.   switch(infix_term_type)
  723.   {   INFIXTT_NUMBER:
  724.           if (brief) "; == ", noun;
  725.           print "; The number ", noun, " == $", (InfixHex) noun;
  726.           if (noun >= 32 && noun < 127) print " == '", (char) noun, "'";
  727.           new_line;
  728.       INFIXTT_NAMEDOBJECT:
  729.           print "~", (name) noun, "~ (", noun, ")^"; if (brief) return;
  730.           <<Showobj noun>>;
  731.       INFIXTT_CONSTANT:
  732.           if (brief) "; == ", noun;
  733.           switch(infix_data1 & 15)
  734.           {   nothing:
  735.                   print "; Constant ", (InfixPrintConstant) infix_parsed_lvalue,
  736.                   " == ", noun, "^";
  737.               Object: <<Showobj noun>>;
  738.               Class: print "Class ", (name) noun, "^";
  739.                   objectloop (a ofclass noun)
  740.                   {   if (flag) print ", "; else print "Contains: ";
  741.                       print (name) a, " (", a, ")"; flag=true;
  742.                   }
  743.                   if (flag==false) "No object is of this class";
  744.           }
  745.           new_line;
  746.       INFIXTT_ATTRIBUTE:
  747.           if (brief) "; == ", noun;
  748.           if (noun>=48 || noun<0) "; No such attribute";
  749.           print "; Attribute ", (InfixPrintAttribute) noun,
  750.               " (numbered ", noun, ")^";
  751.           objectloop (x has noun)
  752.           {   if (flag) print ", ";
  753.               else print "Each of these ~has ", (InfixPrintAttribute) noun, "~: ";
  754.               print (name) x, " (", x, ")"; flag = true;
  755.           }
  756.           if (flag == false) "No object ~has ", (InfixPrintAttribute) noun, "~";
  757.           new_line;
  758.       INFIXTT_PROPERTY:
  759.           if (brief) "; == ", noun;
  760.           print "; Property ", (property) noun, " (numbered ", noun, ")^";
  761.           objectloop (x provides noun)
  762.           {   if (flag) print ", "; else print "Provided by: ";
  763.               print (name) x, " (", x, ")"; flag = true;
  764.           }
  765.           if (flag == false) "Which is not provided by any object";
  766.           new_line;
  767.       INFIXTT_DWORD:
  768.           if (brief) "; == ", noun;
  769.           if (noun == 0) "; This word is not in the dictionary";
  770.           a = noun->#dict_par1;
  771.           print "; Dictionary word '", (address) noun;
  772.           if (a & 4) print "//p";
  773.           print "' (address ", noun, ")";
  774.           if (a)
  775.           {   print ": ";
  776.               if (a & 2) print "meta ";
  777.               if (a & 1) print "verb   ";
  778.               if (a & 8) print "preposition   ";
  779.               if (a & 4) print "pluralising ";
  780.               if (a & 128) print "noun ";
  781.           }
  782.           new_line;
  783.           if (a & 1) <<Showverb noun>>;
  784.       INFIXTT_ROUTINE:
  785.           if (brief) "; == ", noun;
  786.           print "; Routine ", (InfixPrintRoutine) infix_parsed_lvalue,
  787.               " (number ", infix_parsed_lvalue, ",
  788.               packed address ", noun, ")^";
  789.       INFIXTT_GLOBAL:
  790.           if (brief) "; == ", noun;
  791.           print "; Global ", (InfixPrintGlobal) infix_parsed_lvalue,
  792.               " == ", noun, "^";
  793.       INFIXTT_ARRAY:
  794.           if (brief) "; == ", noun;
  795.           print "; Array ", (InfixPrintArray) infix_parsed_lvalue, " ";
  796.           infix_data1 = infix_data1 % 16;
  797.           switch(infix_data1)
  798.           {   0: print "->"; a=0;
  799.               1: print "-->"; a=0;
  800.               2: print "string"; a=1;
  801.               3: print "table"; a=1;
  802.           }
  803.           print " ", infix_data2, "^; == "; b=infix_data2; if (x) b++;
  804.           for (w=b-1:w>=a:w--)
  805.               if (infix_data1 == 0 or 2) { if (noun->w) break; }
  806.               else { if (noun-->w) break; }
  807.           if (b-1-w <= 5) w=b-1;
  808.           for (:x<=w:x++)
  809.               if (infix_data1 == 0 or 2) print noun->x, " ";
  810.               else print noun-->x, " ";
  811.           if (w<a) print "(", b-a, " zero entries)";
  812.           else if (w<b-1) print "(then ", b-1-w, " zero entries)";
  813.           new_line;
  814.       INFIXTT_ACTION:
  815.           if (brief) "; == ", noun;
  816.           if (noun >= #lowest_fake_action_number
  817.               && noun <= #highest_fake_action_number)
  818.              "; Fake action ", (InfixPrintFakeAction) noun,
  819.               " (numbered ", noun, ")^Is not generated by any grammar";
  820.           print "; Action ", (InfixPrintAction) noun,
  821.               " (numbered ", noun, ")^";
  822.           w = 0-->4;
  823.           for (b=0:b<(0-->4 + 5)-->0:b++)
  824.           {   w = 0-->4 + 7 + b*9;
  825.               if ((w->#dict_par1) & 1)
  826.               {   a = (0-->7)-->($ff-(w->#dict_par2));
  827.                   lines = a->0; a++;
  828.                   for (:lines > 0:lines--)
  829.                   {   a = UnpackGrammarLine(a);
  830.                       if (action_to_be == noun)
  831.                       {   print "'", (address) w, "' "; DebugGrammarLine();
  832.                           new_line;
  833.                           flag = true;
  834.                       }
  835.                   }
  836.               }
  837.           }
  838.           if (flag == 0) "Is not generated by any grammar";
  839.       INFIXTT_SYSFUN:
  840.           if (brief) "; == ", noun;
  841.          "; System function ~", (address) infix_parsed_lvalue, "~ has
  842.           not been overridden by any routine and so has its standard
  843.           definition.";
  844.       INFIXTT_STATICSTRING:
  845.           if (brief) "; == ", noun;
  846.           if (metaclass(noun) ~= String) "; ", noun, " is not a string.";
  847.           print "~", (string) noun, "~^";
  848.       INFIXTT_LOGICAL:
  849.           if (noun==true) "; true"; if (noun==false) "; false";
  850.           "; ", noun;
  851.   }
  852. ];
  853. [ InfixDescribeWatchSub x y z s flag aflag;
  854.   print "; The Infix ~;watch~ verb allows you to set a watch on any named
  855.       routine(s) or objects: for instance ~;watch ScoreSub~ or
  856.       ~;watch silver bars~. You can also:
  857.       ^    ~;watch objects~: changes to attribute or property settings";
  858.   if (debug_flag & 8) print " (on)"; else print " (off)";
  859.  
  860.       print ";^    ~;watch timers~: the running of timers and daemons each turn";
  861.   if (debug_flag & 4) print " (on)"; else print " (off)";
  862.  
  863.       print ";^    ~;watch messages~: all messages sent";
  864.   if (debug_flag & 1) print " (on)"; else print " (off)";
  865.  
  866.       print ";^    ~;watch actions~: all actions generated";
  867.   if (debug_flag & 2) print " (on)"; else print " (off)";
  868.  
  869.       print ".^~~;watch~ can be abbreviated to ~;w~ and use ~off~ to stop
  870.       watching: for instance ~;w location off~.^";
  871.   aflag = debug_flag;
  872.   objectloop (x has infix__watching) flag = true; aflag = aflag || flag;
  873.   if (flag) print "The following objects are currently being watched: ";
  874.   flag = false;
  875.   objectloop (x has infix__watching)
  876.   {   if (flag) print ", "; flag = true;
  877.       print (name) x, " (", x, ")";
  878.   }
  879.   if (flag) new_line;
  880.   s = (#highest_routine_number - #lowest_routine_number);
  881.   if (s%8 == 0) s=s/8; else s=s/8+1;
  882.   for (flag=false, x=0:x<s:x++) if (#routine_flags_array->x) flag = true;
  883.   aflag = aflag || flag;
  884.   if (flag) print "The following routines are currently being watched: ";
  885.   for (x=0, flag=false:x<s:x++)
  886.   {   for (y=1,z=0:y<256:z++,y=y*2)
  887.       {   if ((#routine_flags_array->x) & y)
  888.           {   if (flag) print ", "; flag = true;
  889.               print (InfixPrintRoutine)
  890.                   #lowest_routine_number + x*8 + z;
  891.           }
  892.       }
  893.   }
  894.   if (flag) new_line;
  895.   if (aflag == false) "At present, nothing is being watched.";
  896. ];
  897. [ InfixWatchOnSub i j k l;
  898.   if (noun == 0) return InfixDescribeWatchSub();
  899.   if (infix_term_type == INFIXTT_ROUTINE)
  900.   {   i = infix_parsed_lvalue/8;
  901.       for (j=0,k=1:j<infix_parsed_lvalue%8:j++) k=k*2;
  902.       l = #routine_flags_array->i;
  903.       l = l | k;
  904.       @storeb #routine_flags_array i l;
  905.      "; Watching routine ", (InfixPrintRoutine) infix_parsed_lvalue, ".";
  906.   }
  907.   if (metaclass(noun) == Object)
  908.   {   give noun infix__watching;
  909.      "; Watching object ~", (name) noun, "~ (", noun, ").";  
  910.   }
  911.   InfixDescribeWatchSub();
  912. ];
  913. [ InfixWatchOffSub i j k l;
  914.   if (noun == 0) return InfixDescribeWatchSub();
  915.   if (infix_term_type == INFIXTT_ROUTINE)
  916.   {   i = infix_parsed_lvalue/8;
  917.       for (j=0,k=1:j<infix_parsed_lvalue%8:j++) k=k*2;
  918.       l = #routine_flags_array->i;
  919.       l = l & (~k);
  920.       @storeb #routine_flags_array i l;
  921.      "; Not watching ", (InfixPrintRoutine) infix_parsed_lvalue, ".";
  922.   }
  923.   if (metaclass(noun) == Object)
  924.   {   @clear_attr noun infix__watching;
  925.      "; Not watching object ~", (name) noun, "~ (", noun, ").";  
  926.   }
  927.   InfixDescribeWatchSub();
  928. ];
  929. [ InfixList from to tab filter i flag;
  930.   print "^    ";
  931.   for (i=from:i<=to:i++)
  932.       if (tab-->(i-from))
  933.       {   flag = true;
  934.           if (tab == #array_names_array)
  935.           {   Symb__Tab(INFIXTT_ARRAY, i);
  936.               flag = ~~(temp__global3 & 16);
  937.           }
  938.           if (tab == #routine_names_array)
  939.           {   Symb__Tab(INFIXTT_ROUTINE,i);
  940.               flag = ~~(temp__global3 & 16);
  941.           }
  942.           if (tab == #constant_names_array)
  943.           {   Symb__Tab(INFIXTT_CONSTANT,i);
  944.               flag = (~~(temp__global3 & 16)) && (temp__global3 % 16 == filter);
  945.           }
  946.           if (flag) print (string) tab-->(i-from), " ";
  947.       }
  948.   new_line;
  949. ];
  950. [ InfixInvSub i;
  951.  
  952.   print (string) Story, (string) Headline;
  953.   print "  ", (number) #highest_object_number - #lowest_object_number + 1,
  954.       " objects;^";
  955.   print "  non-library object-name constants:";
  956.   InfixList(#lowest_constant_number, #highest_constant_number,
  957.       #constant_names_array, 2);
  958.   print "  ", (number) #highest_class_number - #lowest_class_number + 1,
  959.       "  classes:^    ";
  960.   for (i=#lowest_class_number:i<=#highest_class_number:i++)
  961.       print (name) #class_objects_array-->i, " ";
  962.   new_line;
  963.   print "  non-library arrays:";
  964.   InfixList(#lowest_array_number, #highest_array_number,
  965.       #array_names_array);
  966.   print "  non-library routines:";
  967.   InfixList(#lowest_routine_number, #highest_routine_number,
  968.       #routine_names_array);
  969.   print "  non-library constants:";
  970.   InfixList(#lowest_constant_number, #highest_constant_number,
  971.       #constant_names_array, 0);
  972.   print "  (common) properties:";
  973.   InfixList(#lowest_property_number, 63, #property_names_array);
  974.   print "  (individual) properties:";
  975.   InfixList(64, #highest_property_number, #property_names_array + 126);
  976.   print "  attributes:";
  977.   InfixList(#lowest_attribute_number, #highest_attribute_number,
  978.       #attribute_names_array);
  979.   if (true) return;
  980.   print "  variables:";
  981.   InfixList(#lowest_global_number, #highest_global_number,
  982.       #global_names_array);
  983.   print "  actions:";
  984.   InfixList(#lowest_action_number, #highest_action_number,
  985.       #action_names_array);
  986.   print "  fake actions:";
  987.   InfixList(#lowest_fake_action_number, #highest_fake_action_number,
  988.       #fake_action_names_array);
  989. ];
  990.  
  991. Verb ";i" ";inv" ";inventory"
  992.      * -> InfixInv;
  993. Verb ";x" ";examine"
  994.      * InfixRvalue -> InfixExamine;
  995. Verb ";xo" ";examineo"
  996.      * InfixRvalue -> InfixExamineO;
  997. Verb ";xs" ";examines"
  998.      * InfixRvalue -> InfixExamineS;
  999. Verb ";<"
  1000.      * InfixActionToken -> InfixAction
  1001.      * InfixActionToken InfixRvalue -> InfixAction
  1002.      * InfixActionToken InfixRvalue InfixRvalue -> InfixAction;
  1003. Verb ";"
  1004.      * -> InfixWelcome
  1005.      * InfixRvalue -> InfixEval;
  1006. Verb ";give"
  1007.      * InfixRvalue InfixRvalue -> InfixGive;
  1008. Verb ";move"
  1009.      * InfixRvalue "to" InfixRvalue -> InfixMove;
  1010. Verb ";remove"
  1011.      * InfixRvalue -> InfixRemove;
  1012. Verb ";watch" ";w"
  1013.      * -> InfixWatchOn
  1014.      * "timers"/"daemons" -> TimersOn
  1015.      * "timers"/"daemons" "off" -> TimersOff
  1016.      * "actions" -> ActionsOn
  1017.      * "actions" "off" -> ActionsOff
  1018.      * "messages" -> RoutinesOn
  1019.      * "messages" "off" -> RoutinesOff
  1020.      * "objects" -> ChangesOn
  1021.      * "objects" "off" -> ChangesOff
  1022.      * InfixRvalueTerm -> InfixWatchOn
  1023.      * InfixRvalueTerm "off" -> InfixWatchOff;
  1024.  
  1025. ! ------------------------------------------------------------------------
  1026.